import {parseXML, reduceHTML2SimpleXML, StXML} from "../../../function/xmlFunc";
import {BookUpdater} from "../../BookUpdater";
import {requestText} from "../../../function/httpFunc";
import {joinPath} from "../../../function/fileFunc";

export namespace ListDMZJ {
    export interface TravelBaseNode extends StXML.BaseNode {
        traveled: boolean;
        children: TravelNode[];
    }
    export interface TravelTextNode extends StXML.TextNode {
        traveled: boolean;
    }
    export type TravelNode = TravelBaseNode | TravelTextNode;
}

export class ListDMZJ {
    public readonly bookInfo: BookUpdater.BaseInfo;
    public readonly linkPrefix: string = "https://manhua.dmzj.com/";
    constructor(bookInfo: BookUpdater.BaseInfo) {
        this.bookInfo = bookInfo;
    }
    public async getNewList(): Promise<BookUpdater.SimpleArticleItem[]> {
        const listURL = this.bookInfo.referURL;
        const html = await requestText(listURL);
        const xml = reduceHTML2SimpleXML(html);
        const xmlObj = parseXML(xml);
        return this.getArticleList(xmlObj);
    }
    public getArticleList(rootNode: StXML.BaseNode) {
        let nowNode: ListDMZJ.TravelNode = rootNode as ListDMZJ.TravelBaseNode;
        console.log(rootNode);
        nowNode.traveled = true;
        const targetNodeList: ListDMZJ.TravelBaseNode[] = [];
        while (true) {
            if (nowNode.isText) {
                const textNode = nowNode as ListDMZJ.TravelTextNode;
                textNode.traveled = true;
                nowNode = textNode.parent as ListDMZJ.TravelBaseNode;
            } else {
                const baseNode = nowNode as ListDMZJ.TravelBaseNode;
                if (
                    baseNode.tagName.toLowerCase() === "div" &&
                    (
                        baseNode.attrMap.class === "cartoon_online_border" ||
                        baseNode.attrMap.class === "cartoon_online_border_other"
                    ) &&
                    !baseNode.traveled
                ) {
                    targetNodeList.push(baseNode);
                }
                baseNode.traveled = true;
                nowNode = baseNode.children.find((childNode) => !childNode.traveled) as ListDMZJ.TravelNode;
                if (nowNode == null) {
                    if (baseNode.parent == null) {
                        break;
                    }
                    nowNode = baseNode.parent as ListDMZJ.TravelNode;
                }
            }
        }
        return this.orgArticleList(targetNodeList);
    }
    protected orgArticleList(targetNodeList: ListDMZJ.TravelBaseNode[]): BookUpdater.SimpleArticleItem[] {
        let list: BookUpdater.SimpleArticleItem[] = [];
        targetNodeList.forEach((targetNode) => {
            list = list.concat(this.orgArticleListFromNode(targetNode));
        });
        return list;
    }
    protected orgArticleListFromNode(targetNode: ListDMZJ.TravelBaseNode): BookUpdater.SimpleArticleItem[] {
        const nodeListBox = targetNode.children[0] as ListDMZJ.TravelBaseNode;
        const nodeList = nodeListBox.children as ListDMZJ.TravelBaseNode[];
        const bookId = this.bookInfo.id;
        return nodeList.map((item, index) => {
            const linkNode = item.children[0] as ListDMZJ.TravelBaseNode;
            const textNode = linkNode.children[0] as ListDMZJ.TravelTextNode;
            const prefix = this.linkPrefix;
            const link = linkNode.attrMap.href as string;
            const matchId = link.match(/\/(\d+).shtml/);
            return {
                article_index: parseInt(matchId[1]),
                book_id: bookId,
                download_method: "DMZJ",
                localized: 0,
                name: textNode.text,
                origin_url: joinPath(prefix, link as string),
            };
        });
    }
}
